package wca;

import java.awt.Color;
import robocode.HitByBulletEvent;
import robocode.HitRobotEvent;
import robocode.HitWallEvent;
import robocode.Robot;
import robocode.ScannedRobotEvent;

/**
 * Implements ChinpoGum robot which scans for targets and attempts to ram them. When the target is
 * rammed, ChinpoGum will fire and attempt to ram again.
 * 
 * @author Calvin Wong
 * 
 */
public class ChinpoGum extends Robot {

  // locked target name
  private String target;
  private boolean up = false;
  private boolean down = false;
  private boolean left = false;
  private boolean right = false;

  private boolean wallRobot = false;
  private boolean atWall = false;

  /**
   * The main method that is called when the robot is created.
   */

  public void run() {
    setColors(Color.RED, Color.BLUE, Color.GREEN);
    setAdjustRadarForRobotTurn(true);
    while (true) {
      scan();

      // If the target is moving against the walls.
      if (up && down && left && right) {
        wallRobot = true;
      }
      if (wallRobot) {
        turnRadarRight(360);
        ahead(getBattleFieldHeight());
      }
      turnRadarRight(360);
    }
  }

  /**
   * Handles what to do when a robot is scanned.
   * 
   * @param e When a robot is scanned
   */
  public void onScannedRobot(ScannedRobotEvent e) {

    // Get the target.
    if (target == null) {
      target = e.getName();
    }

    // Check if the robot is using the walls to move.
    if (e.getHeading() == 0) {
      up = true;
    }

    if (e.getHeading() == 90) {
      right = true;
    }

    if (e.getHeading() == 180) {
      down = true;
    }

    if (e.getHeading() == 270) {
      left = true;
    }

    // If the robot is moving against the walls.
    if (wallRobot) {

      // If the target is moving towards the robot.
      if (Math.abs(e.getHeading() - 180) == Math.abs(getHeading()) && e.getBearing() == 0) {
        fire(300 / e.getDistance());
      }

      // If the target is moving away from the robot.
      else if (e.getBearing() == 0) {
        fire(300 / e.getDistance());
      }
    }

    else {
      // Turns the tank towards the target's scanned direction.
      turnRight(e.getBearing());

      // Fire at the robot if it is still.
      if (e.getVelocity() == 0) {
        fire(300 / e.getDistance());
      }

      // Moves the tank into the target's scanned location.
      ahead(e.getDistance() + 5);
    }
  }

  /**
   * Handles collisions with the wall.
   * 
   * @param e When the robot hits the wall
   */
  public void onHitWall(HitWallEvent e) {

    // Move towards the wall and begin moving against the wall.
    if (wallRobot && !atWall) {
      turnRight(-getHeading() + 90);
      atWall = true;
    }

    // Robot has hit a corner.
    else if (wallRobot && atWall) {
      turnLeft(90);
    }

    // Robot has hit a wall.
    else {
      back(30);
    }
  }

  /**
   * Handles collisions with the target.
   * 
   * @param e When the robot rams the target
   */
  public void onHitRobot(HitRobotEvent e) {

    // Fire at the target.
    fire(3);

    // Attempt to ram the target again.
    ahead(5);
  }

  /**
   * Handles robot getting hit by bullets.
   * 
   * @param e When the robot is hit by a bullet
   */
  public void onHitByBullet(HitByBulletEvent e) {
    if (e.getName().equals(target)) {
      turnRight(e.getBearing());
      fire(e.getPower());
      ahead(20);
    }

    // Moves direction if the bullet does not belong to current target.
    else {
      turnLeft(30);
      ahead(20);
    }
  }
}
